package com.onurokan.someone4me.user.dao;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;


import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
import com.onurokan.someone4me.user.domain.User;

@Repository
@Transactional
public class HibernateUserDao implements UserDao {

	private SessionFactory	sessionFactory;

	@Autowired
	private Md5PasswordEncoder passwordEncoder;

	@Autowired
	public HibernateUserDao(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	private Session currentSession() {
		return sessionFactory.getCurrentSession();
	}

	public void addUser(User user) throws ConstraintViolationException {
		String password = passwordEncoder.encodePassword(user.getPassword(), user.getUsername());
		Date birthday = null;
		try {
			birthday = new SimpleDateFormat("dd/MM/yyyy").parse(user.getDay() + "/" + user.getMonth() + "/" + user.getYear());
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		user.setPassword(password);
		user.setBirthday(birthday);
		user.setSchool(SchoolTypeEnum.values()[user.getSchoolId()-1].name());
		user.setEnabled(false);
		// TODO(onur): We might need to guarantee this transaction with txTemplate. Does @Transaction do this for all transactions in this class?
		currentSession().save(user);
	}

	public void saveUser(User user) {
		user.setDay(1);
		user.setMonth(1);
		user.setYear(2000);
		user.setSchoolId(1);
		currentSession().update(user);
	}

	public User loadUserById(Long id) {
		return (User) currentSession().get(User.class, id);
	}

	public User loadUserByUsername(String username) {
		Criteria criteria = currentSession().createCriteria(User.class);
		criteria.add(Restrictions.eq("username", username));
		List<?> list = criteria.list();
		if (list.isEmpty()) {
			return null;
		}
		return (User) list.get(0);
	}

}
